import json
import os
import time
from types import SimpleNamespace
from typing import Any, Dict

import yaml
from nacos import NacosClient

basedir = os.path.abspath(os.path.dirname(__file__))

class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard to guess string'
    FLASKY_ADMIN = os.environ.get('FLASKY_ADMIN')

    # NACOS_SERVER_ADDRESS = os.environ.get('NACOS_SERVER_ADDRESS')
    # NACOS_USERNAME = os.environ.get('NACOS_USERNAME')
    # NACOS_PASSWORD = os.environ.get('NACOS_PASSWORD')
    # NACOS_NAMESPACE = os.environ.get('NACOS_NAMESPACE')
    # NACOS_DATA_ID = os.environ.get('NACOS_DATA_ID')

    NACOS_SERVER_ADDRESS = 'http://52.130.90.34:8848'
    NACOS_USERNAME = 'wxapp_dev'
    NACOS_PASSWORD = 'wxapp.dev'
    NACOS_NAMESPACE = 'ns_wxapp'
    NACOS_DATA_ID = 'eotms-weixin-app'

    @staticmethod
    def init_app(app):
        pass


class DevelopmentConfig(Config):
    DEBUG = True
    TESTING = False
    SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') or \
                              'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite')

class TestingConfig(Config):
    DEBUG = False
    TESTING = True
    SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or \
                              'sqlite:///' + os.path.join(basedir, 'data-testing.sqlite')

class ProductionConfig(Config):
    DEBUG = False
    TESTING = False
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
                              'sqlite:///' + os.path.join(basedir, 'data.sqlite')

config = {
    'development': DevelopmentConfig,
    'testing': TestingConfig,
    'production': ProductionConfig,

    'default': DevelopmentConfig
}


class AppConfig:
    def __init__(self, config_dict: Dict[str, Any]):
        self._data = config_dict

    def __getattr__(self, name: str) -> Any:
        if name in self._data:
            value = self._data[name]
            if isinstance(value, dict):
                return AppConfig(value)
            return value
        raise AttributeError(f"No config item named '{name}'")


class ConfigManager:
    # def __init__(self):
    #     self.config = None
    #
    # def load_from_nacos(self, nacos_client, data_id, group):
    #     # 从Nacos获取配置
    #     yaml_str = nacos_client.get_config(data_id, group)
    #     # 解析YAML
    #     import yaml
    #     config_dict = yaml.safe_load(yaml_str)
    #     # 转换为对象
    #     self.config = json.loads(
    #         json.dumps(config_dict),
    #         object_hook=lambda d: SimpleNamespace(**d)
    #     )
    def __init__(self, nacos_client: NacosClient):
        self.nacos_client = nacos_client
        self.config = None

    def _parse_config(self, yaml_str: str) -> AppConfig:
        try:
            config_dict = yaml.safe_load(yaml_str)
            return AppConfig(config_dict)
        except yaml.YAMLError as e:
            # 处理解析异常
            raise RuntimeError(f"YAML解析失败: {str(e)}")

    def refresh_config(self, data_id: str, group: str):
        # 带MD5校验的配置获取
        new_config = self.nacos_client.get_config(
            data_id, group)
        if new_config is not None:
            self.config = self._parse_config(new_config)

    def start_listening(self, data_id: str, group: str, interval=30):
        # 启动监听线程
        def listener():
            while True:
                self.refresh_config(data_id, group)
                time.sleep(interval)
                print(self.config.buk.eotms.wxapp.app_memo)

        import threading
        thread = threading.Thread(target=listener, daemon=True)
        thread.start()
